package com.googlecode.lazyrecords.memory;

import com.googlecode.lazyrecords.Definition;
import com.googlecode.lazyrecords.Keyword;
import com.googlecode.lazyrecords.Record;
import com.googlecode.lazyrecords.SourceRecord;
import com.googlecode.lazyrecords.mappings.StringMappings;
import com.googlecode.totallylazy.Function1;
import com.googlecode.totallylazy.Maps;
import com.googlecode.totallylazy.Pair;

import java.util.Map;

public class Mapords {
    private final StringMappings mappings;

    public Mapords(StringMappings mappings) {
        this.mappings = mappings;
    }

    public Function1<Map<String, String>, Record> asRecord(final Definition definition) {
        return new Function1<Map<String, String>, Record>() {
            @Override
            public Record call(Map<String, String> data) throws Exception {
                return SourceRecord.record(data, definition.fields().map(values(data)));
            }
        };
    }

    public Function1<Keyword<?>, Pair<Keyword<?>, Object>> values(final Map<String, String> map) {
        return new Function1<Keyword<?>, Pair<Keyword<?>, Object>>() {
            @Override
            public Pair<Keyword<?>, Object> call(Keyword<?> keyword) throws Exception {
                return Pair.<Keyword<?>, Object>pair(keyword, mappings.toValue(keyword.forClass(), map.get(keyword.name())));
            }
        };
    }

    public Function1<Record, Map<String, String>> asMap(final Definition definition) {
        return new Function1<Record, Map<String, String>>() {
            @Override
            public Map<String, String> call(Record record) throws Exception {
                return Maps.map(definition.fields().map(values(record)));
            }
        };
    }

    public Function1<Keyword<?>, Pair<String, String>> values(final Record record) {
        return new Function1<Keyword<?>, Pair<String, String>>() {
            @Override
            public Pair<String, String> call(Keyword<?> keyword) throws Exception {
                return Pair.pair(keyword.name(), mappings.toString(keyword.forClass(), record.get(keyword)));
            }
        };
    }
}
